[小ネタ] OpenCVでWebカメラを使うときに指定する番号を調べる方法
こんにちは。製造ビジネステクノロジー部のakkyです。
OpenCVでWebカメラ画像を使って画像処理をするとき、使用するカメラのIDを指定する必要がありますが、複数のカメラが接続されているときにはどうすればいいでしょうか?
最初が0なので、カメラがもう1台あれば、1でしょうか?
これでうまくいく場合もあるかもしれませんが、私のWindows10環境でうまくいかず、1台目のカメラと同じ画像が表示されてしまいました。
しかも、画像が表示されるまでかなりの時間がかかってしまうという問題もありました。
環境
- Windows10 Pro 64bit
- Python 3.11.9
- opencv-python 4.8.1.78
OpenCVがビデオキャプチャする仕組み
Pythonでopencv-pythonライブラリを使う場合、次のようなコードを書くと思います。
cv2.VideoCapture(0)
ところが、これは省略された書き方になっていて、ドキュメントを読むとapiPreference
という引数があり、デフォルト値はCAP_ANY
という値になっています。
この引数はOpenCVがカメラ画像を取得するためのAPIを指定するものになっていて、私のWindows10環境ではMSMF(Microsoft Media Foundation)とDSHOW(DirectShow)が使われているようでした。
さらに検索すると、MSMFの使用がカメラの初期化がとても遅くなる原因であることがわかりました。(たとえばこのissue)
このため、以下のようにDSHOWバックエンドに切り替えれば問題は解決するはずです。
cv2.VideoCapture(0, cv2.CAP_DSHOW)
IDのみによるバックエンドの指定方法
ところが、OpenCVを利用して作られた外部ツールを使う際には、カメラIDは指定できるが、バックエンドはCAP_ANY固定で指定できないということがあります。
ソースコードを改変すればいいのですが面倒です。
そこで調べてみたところ、cv2-enumerate-camerasというツールを使用すれば、CAP_ANYのときにバックエンドに応じたIDを取得することができました。
pip install cv2_enumerate_cameras
python -m cv2_enumerate_cameras
実行結果をみると、MSMFを使う場合は1400から始まる番号、DSHOWを使う場合は700から始まる番号が割り当てられていることが分かりましたので、カメラIDの指定には0の代わりに700などと指定します。
このツールを使うと、どのIDがどのカメラに割り当てられているのかも簡単に判別できるので便利です。
以上